<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

<script>
// 作用域：程序中某个名字其作用的代码范围
// 通俗讲，某个变量或函数起作用的范围
// JS中作用域有两种：全局作用域和局部作用域（函数作用域）

// 全局作用域：当前页面整个script标签范围内
// 在全局作用域中有一个全局对象 window对象
// console.log( window );// window {...}

// 我们在全局声明的函数和变量，都将挂在window对象下面

// 全局变量（在全局范围都起作用）
var abc = 123;

// 全局函数（在全局范围都起作用）
function aaa(){
    console.log( 456 );
    console.log( abc );// 在函数内部访问abc
}

// console.log( window );// {abc:123,aaa:function(){},...}

// console.log( window.abc );// 123
// window.aaa();

// 通常访问全局的变量和函数不通过window对象，而是直接访问
// console.log( abc );
// aaa();


// 局部作用域：函数作用域（局部变量或函数只在函数内部起作用）
// 在JS中函数是唯一拥有自身作用域的代码块

// if (123) {
//     var a = 1; // 全局变量
// }
// console.log( a );// 1

function fn(){
    var b = 2;// 局部变量
    console.log( b );
}
// fn();
// console.log( b );// 报错，在全局不能访问局部变量


// 同一个作用域中重名会发生覆盖
// 局部变量不会覆盖全局变量
// var num = 666;// 全局变量
// var num = 888;// 全局变量
// function test(){
//     var num = 777;// 局部变量
//     console.log( num );// 777
// }
// test();
// console.log( num );// 888


// 局部变量和形参重名：形参优先使用该名字
// function fun(num){
//     console.log( num );// 456
//     var num = 123;
//     console.log( num );// 123
// }
// fun(456);


// 使用var声明一个变量（全局变量）
var a1 = 11;// 显式声明变量

// 不使用var声明一个变量（全局变量）不推荐
a2 = 22;// 隐式声明变量

console.log( a1 );// 11
console.log( a2 );// 22

function hello(){
    var b1 = 123;// 显式声明变量，局部变量
    //从当前作用域一直往外找，找到全局还是没有则为隐式声明
    b2 = 456;// 隐式声明变量，全局变量，不推荐
}
hello();
console.log( b2 );// 456
console.log( window );

</script>
</body>
</html>